﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;

namespace L4View.BusinessModel.SpyLogMonitor
{
    public class SpyFileSeeker : FileSeeker
    {
        private readonly ManualResetEvent _readEvent;

        private volatile bool _stopWatching;

        private FileSystemWatcher _fileWatcher;

        private long _position;

        public SpyFileSeeker()
            : base()
        {
            _readEvent = new ManualResetEvent(false);
            _stopWatching = false;
        }

        public override void SetOffset(int offset)
        {
            throw new NotImplementedException();
        }

        public override void SetRange(int range)
        {
            throw new NotImplementedException();
        }

        public override WaitHandle StartRead()
        {
            PrepareAndStartWatching();

            return _readEvent;
        }

        protected override string Read()
        {
            _readEvent.WaitOne();

            CheckStopCondition();

            using (var stream = File.OpenText(FileName))
            {
                stream.BaseStream.Position = _position;
                _position = stream.BaseStream.Length;
                
                var text = stream.ReadToEnd();

                _readEvent.Reset();

                return text;
            }            
        }

        private void CheckStopCondition()
        {
            if (_stopWatching)
            {
                _fileWatcher.EnableRaisingEvents = false;
                _fileWatcher.Dispose();
                _fileWatcher = null;
                _position = 0;
            }
        }

        private void PrepareAndStartWatching()
        {
            if (_fileWatcher != null)
                return;

            _fileWatcher = new FileSystemWatcher(Path.GetDirectoryName(FileName), Path.GetFileName(FileName));
            _fileWatcher.Changed += new FileSystemEventHandler(OnFileChanged);
            _fileWatcher.NotifyFilter = NotifyFilters.Size;
            _fileWatcher.IncludeSubdirectories = false;
            // Start watching...
            _fileWatcher.EnableRaisingEvents = true;
        }

        private void OnFileChanged(object sender, FileSystemEventArgs e)
        {
            if (e.ChangeType == WatcherChangeTypes.Changed)
            {
                _readEvent.Set();
            }
        }
    }
}
